本篇是故事二的「重現」篇。
本篇要回答:如何建立一個最小重現,證明兩邊實際使用不同的 interpreter 或套件集合?
Day 07 的採證做完,把兩邊的結果並排,事件軌跡長這樣:
IDE 執行測試
↓
Interpreter A(IDE 設定裡指定的路徑)
↓
環境 A 的套件與版本
↓
結果 A
Terminal 執行測試
↓
PATH 找到 Interpreter B
↓
環境 B 的套件與版本
↓
結果 B
兩條路徑從第二步就分家了。IDE 的 interpreter 來自專案設定(某次點選後就一直留著);Terminal 的 python 來自 "PATH" 由前往後的第一個命中。兩個入口、兩套解析規則,指向兩個環境——而我一直以為自己在跑「同一個測試」。
在並排之前,我以為重現問題就是「把錯誤再跑一次」。但錯誤本身早就重現一百次了,重現失敗不等於理解失敗。真正需要重現的是分歧點:讓兩個原本混在一起的執行環境,第一次被分開看見。
最小重現只需要兩步。第一步,兩邊各跑同一行:
python -c "import sys; print(sys.executable)"
路徑不同,分歧成立。第二步,證明分歧足以造成當初的症狀——在兩邊各跑:
python -m pytest --version
pytest --version
"python -m pytest" 用的是「眼前這個 Python 裡的 pytest」;直接打 "pytest" 用的是 "PATH" 找到的第一個 pytest 執行檔,它可能屬於另一個 Python。當套件只裝在環境 A,環境 B 這邊要嘛 "No module named pytest",要嘛跑起來但 import 的是另一套版本——這正是「已安裝」與「找不到」同時成立的機制。
另外兩條線也並排確認:Shell 啟用 venv 改的是這個 Shell 行程的 "PATH",IDE 根本不經過它;IDE 的 interpreter 設定存在專案或個人設定檔,Terminal 也讀不到它。兩條設定路徑互不知情,沒有任何機制保證它們一致。
區分證據等級。已確認事實:上述指令行為與兩種解析規則(可重現)。合理推論:當初的矛盾症狀由環境分歧充分解釋。尚未排除:個案中是否還疊加了工作目錄或環境變數差異。
留下最小重現的定義:
最小重現不是把錯誤再跑一次,而是讓兩個原本混在一起的執行環境第一次被分開看見。
下一篇(Day 09)追問下一層:程式碼沒有變,為什麼測試結果可以完全不同——直接原因與促成因素分開算帳。